package co.gov.medellin.ssti.sub.model.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import co.gov.medellin.ssti.sub.model.dao.IReporteTotalBeneficiariosDAO;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.vo.RepDetBeneficiarioVO;
import co.gov.medellin.ssti.sub.model.vo.ReporteTotalBeneficiosOtorVO;

public class ReporteTotalBeneficiariosDAOImpl extends BaseDAOImpl implements
		IReporteTotalBeneficiariosDAO {

	public ReporteTotalBeneficiariosDAOImpl(Connection con) {
		super(con);
	}

	public Collection<ReporteTotalBeneficiosOtorVO> findBeneficiarios(
			RepDetBeneficiarioVO criteria) throws DAOException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		// parte adicional de la consulta (criterios de busqueda.)
		StringBuffer queryVars = new StringBuffer();
		StringBuffer sbQueryVars = new StringBuffer();
		List<Object> parametersQuery = new ArrayList<Object>();
		List<Object> parametersSbQuery = new ArrayList<Object>();

		if ((Object) criteria.getCodeSede() != null) {
			queryVars.append(" AND sede.CODIGO = ? ");
			sbQueryVars.append(" AND sede_.CODIGO = ? ");
			parametersQuery.add(criteria.getCodeSede());
			parametersSbQuery.add(criteria.getCodeSede());
		}
		if ((Object) criteria.getCodeSubprograma() != null) {
			queryVars.append(" AND subpro.CODIGO = ? ");
			sbQueryVars.append(" AND subpro_.CODIGO = ? ");
			parametersQuery.add(criteria.getCodeSubprograma());
			parametersSbQuery.add(criteria.getCodeSubprograma());
		}
		if ((Object) criteria.getCodePrograma() != null) {
			queryVars.append(" AND prog.CODIGO = ? ");
			sbQueryVars.append(" AND prog_.CODIGO = ? ");
			parametersQuery.add(criteria.getCodePrograma());
			parametersSbQuery.add(criteria.getCodePrograma());
		}
		if ((Object) criteria.getCodeArea() != null) {
			queryVars.append(" AND area.CODIGO = ? ");
			sbQueryVars.append(" AND area_.CODIGO = ? ");
			parametersQuery.add(criteria.getCodeArea());
			parametersSbQuery.add(criteria.getCodeArea());
		}
		if ((Object) criteria.getDesde() != null
				&& (Object) criteria.getHasta() != null) {
			queryVars
					.append(" AND beneotor.FECHA_BENEFICIO BETWEEN TO_DATE(?,'dd/mm/rrrr') AND TO_DATE(?,'dd/mm/rrrr')");
			sbQueryVars
					.append(" AND beneotor_.FECHA_BENEFICIO BETWEEN TO_DATE(?,'dd/mm/rrrr') AND TO_DATE(?,'dd/mm/rrrr')");
			parametersQuery.add(criteria.getDesde());
			parametersSbQuery.add(criteria.getDesde());
			parametersQuery.add(criteria.getHasta());
			parametersSbQuery.add(criteria.getHasta());
		}
		if ((Object) criteria.getDesde() != null
				&& (Object) criteria.getHasta() == null) {
			queryVars
					.append(" AND beneotor.FECHA_BENEFICIO >= TO_DATE(?,'dd/mm/rrrr')");
			sbQueryVars
					.append(" AND beneotor_.FECHA_BENEFICIO >= TO_DATE(?,'dd/mm/rrrr')");
			parametersQuery.add(criteria.getDesde());
			parametersSbQuery.add(criteria.getDesde());

		}
		if ((Object) criteria.getDesde() == null
				&& (Object) criteria.getHasta() != null) {
			queryVars
					.append(" AND beneotor.FECHA_BENEFICIO <= TO_DATE(?,'dd/mm/rrrr')");
			sbQueryVars
					.append(" AND beneotor_.FECHA_BENEFICIO <= TO_DATE(?,'dd/mm/rrrr')");
			parametersQuery.add(criteria.getHasta());
			parametersSbQuery.add(criteria.getHasta());

		}

		StringBuffer query = new StringBuffer();
		query.append("SELECT COUNT(DISTINCT beneotor.BEN_CODIGO) contador, "
				+ "sede.NOMBRE nomsede, prog.NOMBRE nompro, subpro.NOMBRE nomsubpro, area.NOMBRE secre "

				// subQuery
				+ ", (SELECT COUNT(DISTINCT beneficiario_.codigo) FROM TCS_BEN_PROGRAMA prog_, TCS_BEN_SUBPROGRAMA subpro_, TCS_BEN_BENEFICIO_OTORGADO beneotor_, TCS_BEN_SEDE sede_, TCS_BEN_BENEFICIARIO beneficiario_, TCS_BEN_AREA area_ WHERE beneotor_.SBPR_CODIGO =  subpro_.CODIGO AND area_.codigo = prog_.area_codigo AND beneotor_.SEDE_CODIGO = sede_.CODIGO AND subpro_.PRG_CODIGO = prog_.CODIGO AND beneficiario_.CODIGO = beneotor_.BEN_CODIGO AND prog_.vigencia='A' AND subpro_.vigencia='A'  "
				+ sbQueryVars.toString()
				+ " ) AS TOTAL_BENEFICIARIOS "

				+ "FROM TCS_BEN_PROGRAMA prog, TCS_BEN_SUBPROGRAMA subpro, TCS_BEN_BENEFICIO_OTORGADO beneotor, "
				+ "TCS_BEN_SEDE sede, TCS_BEN_BENEFICIARIO beneficiario, TCS_BEN_AREA area "
				+ "WHERE beneotor.SBPR_CODIGO =  subpro.CODIGO "
				+ "AND area.codigo = prog.area_codigo "
				+ "AND beneotor.SEDE_CODIGO = sede.CODIGO "
				+ "AND subpro.PRG_CODIGO = prog.CODIGO "
				+ "AND beneficiario.CODIGO = beneotor.BEN_CODIGO and prog.vigencia='A' AND subpro.vigencia='A'  ");

		query.append(queryVars.toString());
		query.append(" GROUP BY area.NOMBRE, prog.NOMBRE, subpro.NOMBRE, sede.NOMBRE ");
		query.append(" ORDER BY area.NOMBRE, prog.NOMBRE, subpro.NOMBRE, sede.NOMBRE ");

		ArrayList<ReporteTotalBeneficiosOtorVO> lbeneotor = new ArrayList<ReporteTotalBeneficiosOtorVO>();
		try {
			List<Object> parameters = new ArrayList<Object>();
			parameters.addAll(parametersSbQuery);
			parameters.addAll(parametersQuery);

			pstmt = conn.prepareStatement(query.toString());
			pstmt = setQueryParameters(pstmt, parameters);
			rst = pstmt.executeQuery();

			long totalBeneficiarios = 0;
			int firstRow = 0;

			while (rst.next()) {
				ReporteTotalBeneficiosOtorVO objbeneficios = new ReporteTotalBeneficiosOtorVO();
				objbeneficios.setNombrePrograma(rst.getString("nompro"));
				objbeneficios.setNombreSubprograma(rst.getString("nomsubpro"));
				objbeneficios.setNombreSede(rst.getString("nomsede"));
				objbeneficios.setContador(rst.getLong("contador"));
				objbeneficios.setNombreArea(rst.getString("secre"));

				// total += rst.getLong("contador");
				if (firstRow == 0) {
					totalBeneficiarios = rst.getLong("TOTAL_BENEFICIARIOS");
					firstRow++;
				}
				lbeneotor.add(objbeneficios);
			}

			if (lbeneotor.size() > 0) {
				ReporteTotalBeneficiosOtorVO objbeneficios = new ReporteTotalBeneficiosOtorVO();
				objbeneficios.setNombrePrograma("VALOR TOTAL");
				// String valortotal = String.valueOf(total);
				// objbeneficios.setContador(total);
				objbeneficios.setContador(totalBeneficiarios);
				lbeneotor.add(objbeneficios);
			}

		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(rst, pstmt);
		}
		return lbeneotor;
	}

	public RepDetBeneficiarioVO findFilters(
			RepDetBeneficiarioVO repDetBeneficiarioVO) throws DAOException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		String strQuery = null;
		if (repDetBeneficiarioVO.getCodeSede() != null) {
			strQuery = "SELECT NOMBRE FROM TCS_BEN_SEDE WHERE CODIGO = ? ";
			try {
				pstmt = conn.prepareStatement(strQuery);
				pstmt.setLong(1, repDetBeneficiarioVO.getCodeSede().longValue());
				rst = pstmt.executeQuery();
				rst.next();
				repDetBeneficiarioVO.setNombreSede(rst.getString("NOMBRE"));
			} catch (SQLException e) {
				throw new DAOException(e);
			} finally {
				close(rst, pstmt);
			}
		}
		if (repDetBeneficiarioVO.getCodePrograma() != null) {
			strQuery = "SELECT NOMBRE FROM TCS_BEN_PROGRAMA WHERE CODIGO = ? ";
			try {
				pstmt = conn.prepareStatement(strQuery);
				pstmt.setLong(1, repDetBeneficiarioVO.getCodePrograma()
						.longValue());
				rst = pstmt.executeQuery();
				rst.next();
				repDetBeneficiarioVO.setNombrePrograma(rst.getString("NOMBRE"));
			} catch (SQLException e) {
				throw new DAOException(e);
			} finally {
				close(rst, pstmt);
			}
		}
		if (repDetBeneficiarioVO.getCodeSubprograma() != null) {
			strQuery = "SELECT NOMBRE FROM TCS_BEN_SUBPROGRAMA WHERE CODIGO = ? ";
			try {
				pstmt = conn.prepareStatement(strQuery);
				pstmt.setLong(1, repDetBeneficiarioVO.getCodeSubprograma()
						.longValue());
				rst.next();
				repDetBeneficiarioVO.setNombreSubprograma(rst
						.getString("NOMBRE"));
			} catch (SQLException e) {
				throw new DAOException(e);
			} finally {
				close(rst, pstmt);
			}
		}
		if (repDetBeneficiarioVO.getCodeArea() != null) {
			strQuery = "SELECT NOMBRE FROM TCS_BEN_AREA WHERE CODIGO = ? ";
			try {
				pstmt = conn.prepareStatement(strQuery);
				pstmt.setLong(1, repDetBeneficiarioVO.getCodeArea().longValue());
				rst = pstmt.executeQuery();
				rst.next();
				repDetBeneficiarioVO.setNombreArea(rst.getString("NOMBRE"));
			} catch (SQLException e) {
				throw new DAOException(e);
			} finally {
				close(rst, pstmt);
			}
		}

		return repDetBeneficiarioVO;
	}

}
